package com.gdufe.order.mq;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gdufe.common.entity.OrderEntity;
import com.gdufe.common.exception.ServiceException;
import com.gdufe.order.dto.CreateOrderDto;
import com.gdufe.order.service.OrderAdminService;
import com.gdufe.order.service.OrderUserService;
import com.gdufe.order.vo.UserOrderDetilsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
@RocketMQMessageListener(nameServer = "${rocketmq.name-server}", topic = "seckillorder",
        consumerGroup = "seckill-order", messageModel = MessageModel.BROADCASTING)
public class OrderMQListener implements RocketMQListener<Map<String, Object>> {
    @Autowired
    private OrderUserService orderUserService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderAdminService orderAdminService;
    @Resource(type = RocketMQTemplate.class)
    private RocketMQTemplate rocketMQTemplate;


    public static final String ORDER_KEY = "orderDetails";
    public  static final String SEC_KILL_GOODS_KEY="seckillgoods";



    @Override
    public void onMessage(Map<String, Object> map) {
        log.info("接收到秒杀订单消息");
        //获取订单号
        Object data=map.get("seckill");
        ObjectMapper mapper = new ObjectMapper();
        CreateOrderDto orderDto = mapper.convertValue(data, CreateOrderDto.class);
//        Integer orderId= (Integer) map.get("orderId");
        Long orderId=Long.valueOf((Integer) map.get("orderId"));
        OrderEntity order = orderUserService.getById(orderId);
        //获取操作redis hash类型的操作类
        BoundHashOperations<String,Object ,Object> hashOperations = redisTemplate.boundHashOps(SEC_KILL_GOODS_KEY);
        BoundHashOperations<String, Object, Object> hashOperations2 = redisTemplate.boundHashOps(ORDER_KEY);
        if (order.getStatus()==0){
            log.info("订单状态为未支付，别支付了");
            order.setStatus(2);
            order.setPayResoult(2);
            orderAdminService.updateById(order);
            //订单信息更新到缓存
            UserOrderDetilsVo vo;
            if (hashOperations2.hasKey(order.getId().toString())) {
                vo = (UserOrderDetilsVo) hashOperations2.get(order.getId().toString());
                BeanUtils.copyProperties(order, vo);
                hashOperations2.put(vo.getId().toString(), vo);
            }
        }
        if(order.getStatus()==1){
            log.info("订单状态为已支付，要扣减库存了");
            Map<String, String> hashMap = new HashMap<>();
            hashMap.put("seckillId", orderDto.getSeckillId().toString());
            hashMap.put("productNum", orderDto.getProductNum().toString());
            Message<Map<String, String>> message = MessageBuilder.withPayload(hashMap).build();
            rocketMQTemplate.syncSend("seckillstock", message);
        }
        if (order.getStatus()==2){
            log.info("支付失败，开始回滚");
            //检测订单状态，若订单支付失败，回滚redis库存
            Integer num = Integer.valueOf(hashOperations.get(orderDto.getSeckillId().toString()).toString());
            num+=orderDto.getProductNum();
            hashOperations.put(orderDto.getSeckillId().toString(),num.toString());
        }
    }
}
